import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Validators, FormGroup, FormBuilder, FormArray, AbstractControl } from '@angular/forms';
import { PageConfig } from '@iux/live';
import { Subscription } from 'rxjs';

@Component({
  templateUrl: './complex-form.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styles: [
    `
    .help-description {
      font-size: 12px;
    }
    `
  ]
})
export class ComplexFormComponent implements OnInit {
  constructor(private fb: FormBuilder) { }
  data;
  formGroup: FormGroup;
  // Tooltip类型的错误提示显示
  visible = [
    {
      name: false,
      capacity: false,
      quantity: false
    }
  ];
  // Tooltip类型的错误提示
  errorTip = [
    {
      name: '',
      capacity: '',
      quantity: ''
    }
  ];
  // 表单错误信息
  errorTipsMap = {
    name: {
      required: 'name cannot be empty',
      maxlength: 'Length cannot exceed 5'
    },
    capacity: {
      required: 'capacity cannot be empty'
    },
    quantity: {
      required: 'quantity cannot be empty'
    }
  };

  controlSubscribe: Subscription;

  pageIndex = 0;
  pageSize = 10;
  projectsData = [];

  ngOnInit(): void {
    this.initForm();
    this.data = this.initData();
  }

  initData(): { label: string, isLeaf: boolean }[] {
    return [
      {
        label: 'GB',
        isLeaf: true
      },
      {
        label: 'MB',
        isLeaf: true
      }
    ];
  }

  initForm(): void {
    this.formGroup = this.fb.group({
      projectname: ['', Validators.required],
      projects: this.fb.array([
        this.fb.group({
          name: ['', [Validators.required, Validators.maxLength(5)]],
          capacity: ['1', Validators.required],
          capacityUnit: ['GB', Validators.required],
          quantity: ['1', Validators.required]
        })
      ]),
      host: ['', Validators.required],
      host2: ['', Validators.required],
      protect: ['', Validators.required],
      description: [''],
    });
    this.projectsData = this.getProjectsData();
  }

  getProjectsData(): Record<string, never>[] {
    return new Array((this.formGroup.get('projects') as FormArray).length).fill({});
  }

  pageChange(config: PageConfig): void {
    this.pageIndex = config.pageIndex;
    this.pageSize = config.pageSize;
    this.projectsData = this.getProjectsData();
  }

  isLastPage(): boolean {
    return (this.pageIndex + 1) * this.pageSize >= this.getProjectsData().length;
  }

  add(): void {
    (this.formGroup.get('projects') as FormArray).push(
      this.fb.group({
        name: ['', Validators.required],
        capacity: ['1', Validators.required],
        capacityUnit: ['GB', Validators.required],
        quantity: ['1', Validators.required]
      })
    );
    this.visible.push({
      name: false,
      capacity: false,
      quantity: false
    });

    this.errorTip.push({
      name: '',
      capacity: '',
      quantity: ''
    });
    this.projectsData = this.getProjectsData();
    if (!this.isLastPage()) {
      this.pageIndex++;
    }
  }

  deleteRow(i: number): void {
    (this.formGroup.get('projects') as FormArray).removeAt(i);
    this.projectsData = this.getProjectsData();
  }

  focus(i: number, controlName: string): void {
    const control = (this.formGroup.get('projects') as FormArray).at(i).get(controlName);
    this.checkInvalid(control, controlName, i);

    if (this.controlSubscribe) {
      this.controlSubscribe.unsubscribe();
    }

    this.controlSubscribe = control.statusChanges.subscribe(() => {
      this.checkInvalid(control, controlName, i);
    });
  }

  checkInvalid(control: AbstractControl, controlName: string, i: number): void {
    const invalid = control.invalid && (control.dirty || control.touched);
    this.visible[i][controlName] = invalid;

    if (control.errors) {
      this.errorTip[i][controlName] = this.errorTipsMap[controlName][Object.keys(control.errors)[0]];
    }
  }
}
